
import java.io.PrintStream;

public class UnparseVisitor implements JavaRolePreCompilerVisitor {

    protected PrintStream out;

    public UnparseVisitor(PrintStream o) {
        out = o;
    }
    
    public Object print(ASTCheckMethod node, Object data){
		
		for(int i=0;i<node.jjtGetNumChildren();i++){
			print((SimpleNode)node.jjtGetChild(i),data);
		}
		return data;
		
		
		
	}
    public Object print(SimpleNode node, Object data){
		
		if(!node.isPrintable()) return data;
		Token cursor = node.jjtGetFirstToken();
		
		Token lastToken = node.jjtGetLastToken();
		
		if (node.jjtGetNumChildren()>0){
			
			for (Node child : node.getChildren()){
				//stampo i token prima del figlio
				Token firstOfChild = ((SimpleNode)child).jjtGetFirstToken();
				while(cursor!=firstOfChild){
					
					print(cursor);
					cursor=cursor.next;
				}
				
				//visito il figlio 
				((SimpleNode)child).jjtAccept(this,data);
				
				//se non ho token oltre l'ultimo figlio posso uscire
				
				if (((SimpleNode)child).jjtGetLastToken()==lastToken) return data;				
				//siccome ho ancora da scrivere mi sposto oltre.
				
				cursor=((SimpleNode)child).jjtGetLastToken().next;
				
				
			}
		}
		
		//stampo i token rimanenti
		while(cursor!=lastToken){			
			print(cursor);
			cursor=cursor.next;
		}
		print(cursor);//..compreso l'ultimo
		
		return data;
	}
    
    
    protected void print(Token t){
		
		Token special = t.specialToken;
		if (special!=null){
			while(special.specialToken!=null){
				special=special.specialToken;
			}
			while(special!=null){
				out.print(addUnicodeEscapes(special.image));
				special=special.next;
			}
		}
		out.print(addUnicodeEscapes(t.image));
		
	}

    private String addUnicodeEscapes(String str) {
        String retval = "";
        char ch;
        for (int i = 0; i < str.length(); i++) {
            ch = str.charAt(i);
            if ((ch < 0x20 || ch > 0x7e) &&
                    ch != '\t' && ch != '\n' && ch != '\r' && ch != '\f') {
                String s = "0000" + Integer.toString(ch, 16);
                retval += "\\u" + s.substring(s.length() - 4, s.length());
            } else {
                retval += ch;
            }
        }
        return retval;
    }

    public Object visit(SimpleNode node, Object data) {
        return print(node, data);
    }


    public Object visit(ASTCompilationUnit node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPackageDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTImportDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTModifiers node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTypeDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTCDIRRDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPlayedbyList node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTExtendsList node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTImplementsList node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTEnumDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTEnumBody node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTEnumConstant node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTypeParameters node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTypeParameter node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTypeBound node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTCDIRRBody node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTCDIRRBodyDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTFieldDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTVariableDeclarator node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTVariableDeclaratorId node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTVariableInitializer node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTArrayInitializer node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMethodDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMethodDeclarator node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTFormalParameters node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTFormalParameter node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTConstructorDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTThatBody node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTExplicitConstructorInvocation node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTInitializer node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTType node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTReferenceType node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTClassOrInterfaceType node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTypeArguments node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTypeArgument node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTWildcardBounds node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPrimitiveType node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTResultType node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTName node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTNameList node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAssignmentOperator node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTConditionalExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTConditionalOrExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTConditionalAndExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTInclusiveOrExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTExclusiveOrExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAndExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTEqualityExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTInstanceOfExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTRelationalExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTShiftExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAdditiveExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMultiplicativeExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTUnaryExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPreIncrementExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPreDecrementExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTUnaryExpressionNotPlusMinus node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTCastLookahead node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPostfixExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTCastExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPrimaryExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMemberSelector node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPrimaryPrefix node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTPrimarySuffix node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTLiteral node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTBooleanLiteral node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTNullLiteral node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTArguments node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTArgumentList node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAllocationExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTArrayDimsAndInits node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAssertStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTLabeledStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTBlock node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTBlockStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTLocalVariableDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTEmptyStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTStatementExpression node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTSwitchStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTSwitchLabel node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTIfStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTWhileStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTDoStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTForStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTForInit node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTStatementExpressionList node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTForUpdate node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTBreakStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTContinueStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTReturnStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTThrowStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTSynchronizedStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTTryStatement node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTRUNSIGNEDSHIFT node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTRSIGNEDSHIFT node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAnnotation node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTNormalAnnotation node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMarkerAnnotation node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTSingleMemberAnnotation node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMemberValuePairs node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMemberValuePair node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMemberValue node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTMemberValueArrayInitializer node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAnnotationTypeDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAnnotationTypeBody node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTAnnotationTypeMemberDeclaration node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTDefaultValue node, Object data) {
        return print(node, data);
    }

    public Object visit(ASTThatParameter node, Object data) {
        return print(node, data);
    }

	
	public Object visit(ASTDefineConstructor node, Object data){
		return print(node,data);
	}
	
	public Object visit(ASTVars node, Object data){
		return print(node,data);
	}
	
	
	public Object visit(ASTRelationSelectSet node, Object data){
		return print(node,data);
	}
	
	public Object visit(ASTCheckMethod node, Object data){
		return print(node,data);
	}
	
	public Object visit(ASTTuple node, Object data){
		return print(node,data);
	}
	
	public Object visit(ASTCallToCheck node, Object data){
		return print(node,data);
	}
	
}
